let Devices = {
    //错误码
    errorCode: {
        err_0: "正常",
        err_10000: "未初始化蓝牙适配器",
        err_10001: "当前蓝牙适配器不可用",
        err_10002: "没有找到指定设备",
        err_10003: "连接失败",
        err_10004: "没有找到指定服务",
        err_10005: "没有找到指定特征",
        err_10006: "当前连接已断开",
        err_10007: "当前特征不支持此操作",
        err_10008: "其余所有系统上报的异常",
        err_10009: "Android 系统特有，系统版本低于 4.3 不支持 BLE",
        err_10012: "连接超时",
        err_10013: "连接deviceId为空或格式不正确",
    },
    //获取错误码信息
    getErrorMessage(error_code){
        return Devices.errorCode[error_code] || "已连接|未知";
    },
    //是否已初始化过
    hasStart: false,
    //初始化
    start(){
        if(Devices.hasStart) return;
        //监听发现低功耗蓝牙设备时需要做的处理
        wx.onBluetoothDeviceFound(res => {
            let device = res.devices[0];
            if(device.name.toString().length > 0 && device.name.indexOf("未知") === -1){
                //处理设备信息
                let exists = Devices.deviceIndex(device.deviceId);
                if(exists === -1) {
                    let new_device = {
                        name: device.name,
                        deviceId: device.deviceId,
                        RSSI: device.RSSI
                    };
                    Devices.list.push(new_device);
                    //仅在是真正的设备时，才回调
                    if(Devices.eventsOnDeviceFound.length > 0){
                        for(let i=0; i<Devices.eventsOnDeviceFound.length; i++){
                            if(typeof Devices.eventsOnDeviceFound[i] === "function"){
                                //执行事件
                                Devices.eventsOnDeviceFound[i](new_device);
                            }
                        }
                    }
                }
            }
        });
        //监听蓝牙模块状态改变
        wx.onBluetoothAdapterStateChange(res => {
            //console.log("adapter change", res);
            if(res.discovering !== Devices.discovering){
                //Devices.discovering = res.discovering;
                if(Devices.eventsOnAdapterStateChange.length > 0){
                    for(let i=0; i<Devices.eventsOnAdapterStateChange.length; i++){
                        if(typeof Devices.eventsOnAdapterStateChange[i] === "function"){
                            //执行事件
                            Devices.eventsOnAdapterStateChange[i](res);
                        }
                    }
                }
            }
        });
        //监听设备的连接情况（断开、连接成功）
        wx.onBLEConnectionStateChange(res => {
            //根据ID去获取
            Devices.list.forEach((item, index) => {
                if(item.deviceId === res.deviceId){
                    Devices.list[index].connected = res.connected;
                    if(Devices.eventsOnConnectionStateChange.length > 0){
                        for(let i=0; i<Devices.eventsOnConnectionStateChange.length; i++){
                            if(typeof Devices.eventsOnConnectionStateChange[i] === "function"){
                                //执行事件
                                Devices.eventsOnConnectionStateChange[i](res);
                            }
                        }
                    }
                }
            });
        });
        //
        Devices.hasStart = true;
    },
    //发现设备时的回调，支持多个事件同时触发
    eventsOnDeviceFound: [],
    onDeviceFound(callback){
        Devices.eventsOnDeviceFound.push(callback);
    },
    //蓝牙设备状态改变
    eventsOnAdapterStateChange: [],
    onAdapterStateChange(callback){
        Devices.eventsOnAdapterStateChange.push(callback);
    },
    //连接状态改变
    eventsOnConnectionStateChange: [],
    onConnectionStateChange(callback){
        Devices.eventsOnConnectionStateChange.push(callback);
    },
    //停止
    stop(){
        if(Devices.hasStart){
            //停止监听
            wx.offBluetoothAdapterStateChange();
            wx.offBLEConnectionStateChange();
            wx.offBluetoothDeviceFound();
            Devices.list = [];
            Devices.connected_list = [];
            if(Devices.discovering){
                Devices.stopDiscovery();
            }
            Devices.discovering = false;
            Devices.eventsOnDeviceFound = [];
            Devices.eventsOnAdapterStateChange = [];
            Devices.eventsOnConnectionStateChange = [];
            Devices.hasOpenAdapter = false;
            Devices.hasStart = false;
        }
    },
    //已发现的设备列表
    list: [],
    //已连接设备列表
    connected_list: [],
    //是否已初始化蓝牙模块
    hasOpenAdapter: false,
    //初始化蓝牙模块
    openAdapter(callback){
        wx.openBluetoothAdapter({
            mode: "central",
            success: res => {
                Devices.hasOpenAdapter = res.errMsg.indexOf("ok") > 0;
                if(typeof callback === "function") {
                    callback({
                        error: 0,
                        message: res.errMsg.indexOf("ok") === -1 ? res.errMsg : "打开成功"
                    });
                }
            },
            fail: error => {
                if (error.errMsg.indexOf("already opened") > 0) {
                    Devices.hasOpenAdapter = true;
                    if (typeof callback === "function") {
                        callback({
                            error: 0,
                            message: "已打开，无需重复执行"
                        });
                    }
                } else {
                    Devices.hasOpenAdapter = false;
                    if (typeof callback === "function") {
                        callback({
                            error: 1,
                            message: "未能初始化蓝牙设备"
                        });
                    }
                }
            }
        });
    },
    //是否正在搜索设备
    discovering: false,
    //搜索发现设备
    discovery(callback){
        if(Devices.discovering) return;
        if(!Devices.hasOpenAdapter){
            Devices.openAdapter(res => {
                if(res.error > 0){
                    if(typeof callback === "function") {
                        callback(res);
                    }
                }else{
                    Devices.discovery(callback);
                }
            });
        }else{
            wx.startBluetoothDevicesDiscovery({
                success: res => {
                    Devices.discovering = res.isDiscovering;
                    if(typeof callback === "function") {
                        callback({
                            error: 0,
                            message: "搜索设备中"
                        });
                    }
                },
                fail: err => {
                    if(err.errMsg.indexOf("already discovering")){
                        Devices.discovering = true;
                        if(typeof callback === "function") {
                            callback({
                                error: 0,
                                message: "正在搜索，无需重复执行"
                            });
                        }
                    }else{
                        Devices.discovering = false;
                        if(typeof callback === "function") {
                            callback({
                                error: err.errCode,
                                message: err.errMsg
                            });
                        }
                    }
                }
            });
        }
    },
    //停止搜寻附近的蓝牙外围设备，若已经找到需要的蓝牙设备并不需要继续搜索时，建议调用该接口停止蓝牙搜索。
    stopDiscovery(callback){
        if(Devices.discovering){
            wx.stopBluetoothDevicesDiscovery({
                success: res => {
                    Devices.discovering = false;
                    if(typeof callback === "function"){
                        callback({
                            error: 0,
                            message: "已停止搜索"
                        });
                    }
                },
                fail: err => {
                    if(typeof callback === "function") {
                        callback({
                            error: 1,
                            message: err.errMsg
                        });
                    }
                }
            });
        }else{
            callback({
                error: 0,
                message: "已停止搜索设备"
            });
        }
    },
    //连接设备
    connectDevice(deviceId, callback){
        let index = Devices.deviceIndex(deviceId);
        if(index >= 0){
            let device = Devices.list[index];
            if(device.connected){
                //已连接，查看服务状态
                if(device.serviceId == undefined || device.serviceId == null || device.serviceId == ""){
                    //获取服务
                    Devices.getService(deviceId, res4 => {
                        if(res4.error){
                            if(typeof callback === "function"){ callback(res4); }
                        }else{
                            //附加信息
                            device.serviceId = res4.data.serviceId;
                            device.isPrimary = res4.data.isPrimary;
                            device.characteristicId = res4.data.characteristicId;
                            //更新信息
                            Devices.list[index] = device;
                            if(typeof callback === "function"){
                                callback({
                                    error: 0,
                                    device: device
                                });
                            }
                        }
                    });
                }else if(device.characteristicId == undefined || device.characteristicId == null || device.characteristicId == ""){
                    //获取服务特征
                    Devices.getCharacteristic(deviceId, device.serviceId, res3 => {
                        if(res3.error){
                            if(typeof callback === "function"){
                                callback(res3);
                            }
                        }else{
                            device.characteristicId = res3.data.uuid;
                            Devices.list[index].characteristicId = device.characteristicId;
                            if(typeof callback === "function"){
                                callback({
                                    error: 0,
                                    device: device
                                });
                            }
                        }
                    });
                }else{
                    //该设备已连接，并取得了相应的信息
                    callback({
                        error: 0,
                        device: device
                    });
                }
            }else{
                //连接，并取得服务
                Devices.openAdapter(() => {
                    wx.createBLEConnection({
                        deviceId: deviceId,
                        //超时设置为10秒
                        timeout: 10000,
                        //
                        success: res => {
                            if(res.errCode > 0){
                                //有错误
                                if(typeof callback === "function"){
                                    callback({
                                        error: res.errCode,
                                        message: Devices.getErrorMessage(res.errCode)
                                    });
                                }
                            }else{
                                //同时取得
                                Devices.getService(deviceId, res2 => {
                                    if(res2.error){
                                        if(typeof callback === "function"){ callback(res2); }
                                    }else{
                                        //附加信息
                                        device.serviceId = res2.data.serviceId;
                                        device.isPrimary = res2.data.isPrimary;
                                        device.characteristicId = res2.data.characteristicId;
                                        //更新信息
                                        Devices.list[index] = device;
                                        if(typeof callback === "function"){
                                            callback({
                                                error: 0,
                                                device: device
                                            });
                                        }
                                    }
                                });
                            }
                        },
                        fail: err => {
                            if(typeof callback === "function"){
                                callback({
                                    error: 1,
                                    message: "未能连接设备"
                                });
                            }
                        }
                    });
                });
            }
        }
    },
    disconnect(deviceId){
        let device = Devices.getDeviceById(deviceId);
        if(device && device.connected){
            wx.closeBLEConnection({
                deviceId: deviceId,
                success: () => {

                },
                fail: () => {
                    this.showMessage("无法断开连接");
                }
            });
        }
    },
    //仅获取全服务特征的服务ID
    getService(deviceId, callback){
        wx.getBLEDeviceServices({
            deviceId: deviceId,
            success: res => {
                if(res.services){
                    let hasCallback = false;
                    for(let i=0; i<res.services.length; i++){
                        if(hasCallback){
                            break;
                        }
                        let service = res.services[i];
                        Devices.getCharacteristic(deviceId, service.uuid, res2 => {
                            if(!res2.error){
                                //
                                let characteristic = res2.data || {};
                                let characteristicId = characteristic.uuid || null;
                                if(typeof callback === "function" && !hasCallback && characteristicId){
                                    hasCallback = true;
                                    callback({
                                        error: 0,
                                        data: {
                                            serviceId: service.uuid,
                                            isPrimary: service.isPrimary,
                                            characteristicId: characteristicId
                                        }
                                    });
                                }
                            }
                        });
                    }
                }else{
                    if(typeof callback === "function"){
                        callback({
                            error: 1,
                            message: "未能取得设备服务"
                        });
                    }
                }
            },
            fail: err => {
                if(typeof callback === "function"){
                    callback({
                        error: 1,
                        message: "无法获取服务"
                    });
                }
            }
        });
    },
    //获取服务特征
    getCharacteristic(deviceId, serviceId, callback){
        wx.getBLEDeviceCharacteristics({
            deviceId: deviceId,
            serviceId: serviceId,
            success: res => {
                if(res.characteristics){
                    //只取属性值合适的特征
                    let characteristics = null;
                    for(let i = 0; i<res.characteristics.length; i++){
                        /*
                        read: boolean,
                        write: boolean,
                        notify: boolean,
                        indicate: boolean,
                        writeNoResponse: boolean, //不一定有
                        writeDefault: boolean
                        */
                        let cs = res.characteristics[i];
                        if(cs.properties.read && cs.properties.write && cs.properties.notify && cs.properties.indicate){
                            characteristics = cs;
                            break;
                        }
                    }
                    if(typeof callback === "function"){
                        callback({
                            error: 0,
                            data: characteristics
                        });
                    }
                }else{
                    if(typeof callback === "function"){
                        callback({
                            error: 1,
                            message: "未能取得设备的服务特征"
                        });
                    }
                }
            },
            fail: err => {
                if(typeof callback === "function"){
                    callback({
                        error: 1,
                        message: "无法获取特征"
                    });
                }
            }
        });
    },
    //查找设备
    deviceIndex(deviceId){
        for(let i = 0; i < Devices.list.length; i++){
            if(Devices.list[i].deviceId === deviceId){
                return i;
            }
        }
        return -1;
    },
    //根据ID获取设备信息
    getDeviceById(deviceId){
        let index = Devices.deviceIndex(deviceId);
        if(index >= 0){
            return Devices.list[index];
        }
        return null;
    },
    //设备传输单元最大值
    setMTU(deviceId, mtu, callback){
        let device = Devices.getDeviceById(deviceId);
        if(device){
            wx.setBLEMTU({
                deviceId: deviceId,
                mtu: mtu,
                success: res => {
                    if(typeof callback === "function"){
                        callback({
                            error: 0,
                            mtu: res.mtu
                        });
                    }
                },
                fail: err => {
                    if(typeof callback === "function"){
                        callback({
                            error: 1,
                            message: "无法协商MTU"
                        });
                    }
                }
            });
        }
    },
    //发送数据
    writeCharacteristicValue(deviceId, buffer, mtu, callback){
        let device = Devices.getDeviceById(deviceId);
        if(device === null){
            device = {
                connected: false,
                deviceId: deviceId,
                RSSI: 0,
                name: "指定设备"
            };
            Devices.list.push(device);
        }
        if(!device.connected){
            Devices.connectDevice(deviceId, res => {
                if(res.error){
                    callback({
                        error: 1,
                        message: "无法连接设备"
                    });
                }else{
                    Devices.writeCharacteristicValue(deviceId, buffer, mtu, callback);
                }
            });
        }else if(device.serviceId == null || device.serviceId == undefined || device.serviceId == ""){
            Devices.getService(deviceId, res => {
                if(res.error){
                    callback({
                        error: 1,
                        message: "未能获取设备服务"
                    });
                }else{
                    Devices.writeCharacteristicValue(deviceId, buffer, mtu, callback);
                }
            });
        }else if(device.characteristicId == null || device.characteristicId == undefined || device.characteristicId == ""){
            Devices.getCharacteristic(deviceId, device.serviceId, res => {
                if(res.error){
                    callback({
                        error: 1,
                        message: "未能获取设备服务特征"
                    });
                }else{
                    if(res.data == null){
                        callback({
                            error: 1,
                            message: "该设备无法使用，不符合打印特征。"
                        });
                    }else{
                        Devices.writeCharacteristicValue(deviceId, buffer, mtu, callback);
                    }
                }
            });
        }else {
            //开始处理
            let rows = buffer.byteLength;
            let total = mtu;
            let pages = Math.ceil(rows / total);
            for(let page = 0; page < pages; page++){
                //console.log(page, pages);
                let offset = page * total;
                let end = offset + total;
                let _buffer = buffer.slice(offset, end > rows ? rows : end);
                wx.writeBLECharacteristicValue({
                    deviceId: device.deviceId,
                    serviceId: device.serviceId,
                    characteristicId: device.characteristicId,
                    value: _buffer,
                    success: (res) => {
                        //发送成功
                        callback({
                            error: 0,
                            pages: pages,
                            page: page+1
                        });
                        //console.log("write success", (page+1) + "/" + pages);
                    },
                    fail: (err) => {
                        callback({
                            error: 1,
                            pages: pages,
                            page: page+1,
                            message: "未能发送打印数据"
                        });
                        console.log("write fail", (page+1) + "/" + pages);
                    }
                })
            }
        }
    }
};
exports.Devices = Devices;